<?php
/**
 * Base Controller class
 * All controllers must extend from this
 */
namespace PUF;

class Controller {
	protected $view = '';
	
	protected $View = null;
	
	protected $viewVars = [];
	
	protected $method = '';
	
	protected $models = [];
	
	protected $params = [];
	
	/**
	 * Entry point. This function does all the pre and post processing,
	 * determines the view, if any, and calls the $method
	 * @param string $method
	 */
	public function _execute() {
		if (!$this->method) {
			throw new \Exception(
				__METHOD__ . '() => No method set!'
			);
		}
		
		$this->_before();
		
		call_user_func_array([$this, $this->method], $this->getUnnamedParams());
		
		$this->_after();
		
		$this->_render();
	}
	
	/**
	 * Called before the selected method
	 */
	protected function _before() {
		$this->setView($this->_getClassName($this) . '/' . $this->method);

		arrayizeObject($this->models);
		
		$Loader = Loader::getInstance();
		foreach ($this->models as $model) {
			$Loader->load($model, ['type' => 'model']);
		}
		
		$Loader = Loader::getInstance();
		$Loader->load('View');
		$this->View = new View();
		$this->View->setView($this->view);
	}
	
	/**
	 * Called after the selected method
	 */
	protected function _after() {
		
	}
	
	public function getView() {
		return $this->view;
	}
	
	public function setView($view) {
		$this->view = $view;
	}
	
	public function getMethod() {
		return $this->method;
	}
	
	public function setMethod($method) {
		$this->method = $method;
	}
	
	public function getParams() {
		return $this->params;
	}
	
	public function setParams($params) {
		$arrParams = explode('/', $params);
		foreach ($arrParams as $param) {
			$arrParam = explode(':', $param);
			if (count($arrParam) == 2) {
				$this->params[$arrParam[0]] = $arrParam[1];
			} else {
				if ($arrParam[0]) {
					$this->params[] = $arrParam[0];
				}
			}
		}
	}
	
	/**
	 * Called lastly to call the corresponding view
	 */
	protected function _render() {
		$this->View->render($this->viewVars);
	}
	
	protected function _getClassName($class) {
		$className = explode('\\', get_class($class));
		return end($className);
	}
	
	protected function setVar($key, $value) {
		$this->viewVars[$key] = $value;
	}
	
	protected function paramExists($param) {
		return isset($this->params[$param]);
	}
	
	protected function getParam($param) {
		return $this->params[$param];
	}
	
	protected function getUnnamedParams() {
		$unnamedParams = [];

		foreach ($this->params as $key => $param) {
			if (is_numeric($key)) {
				$unnamedParams[] = $param;
			}
		}
		
		return $unnamedParams;
	}
	
	public function View() {
		return $this->View;
	}
}